
`include "common_header.verilog" 

//  *************************************************************************
//  File : sdpm_gen.v
//  *************************************************************************
//  This program is controlled by a written license agreement.
//  Unauthorized reproduction or use is expressly prohibited. 
//  Copyright (c) 2001-2011 Morethanip, Germany
//  Designed by Francois Balay
//  info@morethanip.com
//  *************************************************************************
//  Description: Dual Port Memory.
//
//  Synthesis Option: MTIPSDPM_GEN_READEN
//               Implement a read enable signal for the read port.
//               When the optional read enable is implemented, the read data
//               output keeps the current value when read enable is 0 
//               (i.e. does NOT produce arbitrary output).
//               Note: The model may no longer be used for memory inferral
//                     when the read enable option is implemented.
//
//  Version    : $Id: sdpm_gen.v,v 1.2 2013/02/24 10:40:07 dk Exp $
//  *************************************************************************

module sdpm_gen (

   wad,
   din,
   wclk,
   rclk,
   wren,
`ifdef MTIPSDPM_GEN_READEN
   rden,
`endif   
   rad,
   dout);
   
parameter FF_WIDTH      = 4;
parameter DEPTH         = 128;
parameter ADDR_WIDTH    = 7;

input   [ADDR_WIDTH - 1:0] wad;         // Write Address 
input   [FF_WIDTH - 1:0] din;           // Write data in
input   wclk;                           // Write Clock
input   rclk;                           // Read clock
input   wren;                           // Write enable
`ifdef MTIPSDPM_GEN_READEN
input   rden;                           // Read enable
`endif   
input   [ADDR_WIDTH - 1:0] rad;         // Read Address
output  [FF_WIDTH - 1:0] dout;          // Read data out
 
`ifdef MTIPSDPM_GEN_READEN

        // with read-enable
reg     [FF_WIDTH - 1:0] dout; 

`else

        // no read enable
wire    [FF_WIDTH - 1:0] dout; 
reg     [ADDR_WIDTH - 1:0] rad_reg;

`endif

reg     [FF_WIDTH - 1:0] dpram [DEPTH - 1:0];   //  syn_ramstyle = "no_rw_check"

// -----
// Write 
// -----
always @(posedge wclk)
   begin
   if (wren == 1'b 1)
      begin
      dpram[wad] <= din;	
      end
   end

// -----
// Read
// -----
`ifdef MTIPSDPM_GEN_READEN

// read with read enable

always @(posedge rclk)
   begin 
        // read current data with one cycle delay and keep it when rden de-asserts.  
        if( rden == 1'b 1 )
        begin
                dout <= dpram[rad];
        end
   end

`else

// no read enable, allows memory inferral

always @(posedge rclk)
   begin   
      rad_reg <= rad;	
   end
   
assign dout = dpram[rad_reg];	

`endif

endmodule // module sdpm_gen